using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Core.Runtime;
using Cysharp.Threading.Tasks;
using Hotfix.Runtime;
using UnityEngine;

namespace Hotfix.Runtime
{
    [RequireComponent(typeof(RectTransform))]
    [DisallowMultipleComponent]
    public abstract class UIBase : MonoBehaviour, IUILifecycle
    {
        #region 字段与属性
        // 生命周期控制
        private CancellationTokenSource _lifecycleCts;
        public virtual bool AutoDestroy { get; set; } = true;
        protected CancellationToken LifecycleToken => _lifecycleCts?.Token ?? CancellationToken.None;

        // 事件管理
        private readonly EventGroup _eventGroup = new EventGroup();

        // UI层级管理
        private readonly Dictionary<Type, UIBase> _children = new Dictionary<Type, UIBase>();
        protected UIManager UIManager { get; private set; }
        #endregion

        #region UI生命周期接口实现
        public virtual UniTask OnInitialize()
        {
            _lifecycleCts = new CancellationTokenSource();
            UIManager = PersistentObjects.GetComponent<UIManager>();
            UIBindingSystem.AutoBind(this);
            return UniTask.CompletedTask;
        }

        public virtual UniTask OnPreShow() => UniTask.CompletedTask;
        public virtual UniTask OnShow() => UniTask.CompletedTask;
        public virtual UniTask OnPreHide() => UniTask.CompletedTask;
        public virtual UniTask OnHide() => UniTask.CompletedTask;

        public virtual async UniTask OnDispose()
        {
            await CloseAllChildren();
            _eventGroup.RemoveAllListener();
            _lifecycleCts?.Cancel();
            _lifecycleCts?.Dispose();
            _lifecycleCts = null;
        }
        #endregion

        #region 事件管理
        protected void AddListener<TEvent>(Action<IEventMessage> listener) where TEvent : IEventMessage 
            => _eventGroup.AddListener<TEvent>(listener);

        protected void RemoveListener<TEvent>(Action<IEventMessage> listener) where TEvent : IEventMessage 
            => Event.RemoveListener<TEvent>(listener);
        #endregion

        #region 子UI管理
        public virtual void OnUpdate()
        {
            foreach (var child in _children.Values.Where(c => c.gameObject.activeSelf))
            {
                child.OnUpdate();
            }
        }

        public virtual void OnLateUpdate()
        {
            foreach (var child in _children.Values.Where(c => c.gameObject.activeSelf))
            {
                child.OnLateUpdate();
            }
        }

        public async UniTask<T> AddChild<T>() where T : UIBase
        {
            var childType = typeof(T);
            if (_children.TryGetValue(childType, out var existing))
            {
                Debug.LogWarning($"子UI {childType.Name} 已存在，将替换实例");
                await RemoveChild<T>();
            }

            var child = await UIManager.Show<T>();
            child.transform.SetParent(transform, false);
            child.AutoDestroy = true;
            _children[childType] = child;
            return child;
        }

        public async UniTask RemoveChild<T>() where T : UIBase => await RemoveChild(typeof(T));

        private async UniTask RemoveChild(Type childType)
        {
            if (_children.TryGetValue(childType, out var child))
            {
                await UIManager.Hide(childType);
                _children.Remove(childType);
            }
        }

        public T GetChild<T>() where T : UIBase 
            => _children.TryGetValue(typeof(T), out var child) ? (T)child : null;

        public async UniTask CloseAllChildren()
        {
            var tasks = _children.Keys.Select(RemoveChild).ToList();
            await UniTask.WhenAll(tasks);
            _children.Clear();
        }
        #endregion
    }
}
